﻿#region Usings

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
using Box2DX.Dynamics;
using SilverBox.Physics;

#endregion

namespace SilverBox.Behaviors
{
    public class MouseDragJoint : Behavior<FrameworkElement>
    {
        private Entity entity;
        private bool isMouseCaptured = false;
        private MouseJoint joint;
        private Point mouseDownPt;

        protected override void OnAttached()
        {
            base.OnAttached();


            AssociatedObject.MouseLeftButtonDown += HandleMouseDown;
            AssociatedObject.MouseLeftButtonUp += HandleMouseUp;
            AssociatedObject.MouseMove += HandleMouseMove;
            AssociatedObject.LostMouseCapture += HandleLostCapture;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
        }

        private void HandleMouseDown(object sender, MouseButtonEventArgs e)
        {
            entity = Entity.GetElementEntity(AssociatedObject);

            if (entity != null && AssociatedObject.CaptureMouse())
            {
                var mouseJointDef = new MouseJointDef();
                mouseJointDef.Body1 = entity.Simulator.World.GetGroundBody();
                mouseJointDef.Body2 = entity.Body;
                mouseJointDef.MaxForce = 3000;
                mouseJointDef.TimeStep = 1.0f/30;
                mouseJointDef.Target =
                    entity.Simulator.SimulatorContext.ScreenToWorld(e.GetPosition(entity.Simulator.PhysicsContext.Host));

                joint = (MouseJoint) entity.Simulator.World.CreateJoint(mouseJointDef);


                isMouseCaptured = true;

                mouseDownPt = e.GetPosition(AssociatedObject);

                //this.entity.Body.PutToSleep();
            }
        }

        private void HandleMouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseCaptured)
            {
                Point pt = e.GetPosition(entity.Simulator.PhysicsContext.Host);

                joint.SetTarget(entity.Simulator.SimulatorContext.ScreenToWorld(pt));
            }
        }

        private void HandleMouseUp(object sender, MouseEventArgs e)
        {
            AssociatedObject.ReleaseMouseCapture();
        }

        private void HandleLostCapture(object sender, MouseEventArgs e)
        {
            if (isMouseCaptured && joint != null)
            {
                isMouseCaptured = false;


                entity.Simulator.World.DestroyJoint(joint);

                joint = null;

                //this.entity.Body.PutToSleep();

                //this.entity.Body.WakeUp();
            }
        }
    }
}